<template>
  <div class="flex h-full flex-col bg-#f7f9fc z-20 app-crud">
    <AppCard v-if="$slots.default || $slots.action" :border="false">
      <form
        class="flex justify-between"
        style="
          box-shadow:
            rgba(0, 0, 0, 0.1) 0 0 4px,
            rgba(9, 30, 66, 0.08) 0 1px 10px;
        "
      >
        <div class="flex-1 flex pb-12 pt-12 px-20">
          <div class="flex-1 flex">
            <slot></slot>
          </div>
          <div class="flex-shrink-0">
            <a-space>
              <!--              <a-tooltip placement="bottom" title="查询">-->
              <!--                <a-button @click="handleQuery" attr-type="submit">-->
              <!--                  <template #icon>-->
              <!--                    <SearchOutlined></SearchOutlined>-->
              <!--                  </template>-->
              <!--                </a-button>-->
              <!--              </a-tooltip>-->
              <a-tooltip placement="bottom" title="重置" v-if="$slots.default">
                <a-button type="text" @click="handleReset">
                  <template #icon>
                    <ReloadOutlined></ReloadOutlined>
                  </template>
                </a-button>
              </a-tooltip>
              <slot name="action"></slot>
            </a-space>
          </div>
        </div>
      </form>
    </AppCard>

    <AppCard class="flex-1 mt-8 overflow-hidden" border>
      <div class="flex wh-full overflow-hidden">
        <slot name="left" v-if="$slots.left"></slot>
        <div class="flex-1 flex-col flex" w-full>
          <div class="flex-1 overflow-hidden" ref="tableWrap">
            <a-table
              size="small"
              :data-source="tableData"
              :loading="loading"
              :pagination="false"
              :columns="columns"
              column-resizable
              :scroll="scroll"
              v-if="isTable"
            >
              <template #bodyCell="{ column, record }">
                <component v-if="column.render" :is="column.render({ record, column })"></component>
                <template v-else>{{ record[column.dataIndex] }}</template>
              </template>
            </a-table>
            <slot name="data" :record="tableData" v-else></slot>
          </div>
          <div
            class="h-50 bg-#fbfbfb flex items-center px-20"
            border-t="1px solid light_border"
            v-if="props.isPagination"
          >
            <a-pagination
              :simple="false"
              :show-total="(total, range) => `${range[0]}-${range[1]} 共 ${total} 条`"
              show-less-items
              show-size-changer
              show-quick-jumper
              show-title
              @change="onPageChange"
              v-model:current="pagination.current"
              :total="pagination.total"
            ></a-pagination>
          </div>
        </div>
      </div>
    </AppCard>
  </div>
</template>

<script setup lang="ts">
import AppCard from './AppCard.vue'
import useLoading from '@/hooks/loading'
import { PageQueryDto } from '@/api/types'
import utils from 'xe-utils'

const props = defineProps({
  query: {
    type: Object,
    default() {
      return {}
    },
  },
  getData: {
    type: Function,
    required: true,
  },
  isPagination: {
    type: Boolean,
    default: true,
  },
  remote: {
    type: Boolean,
    default: true,
  },
  columns: {
    type: Array,
    required: true,
  },
  defaultSort: {
    type: String,
    default: 'weight',
  },
  isTable: {
    type: Boolean,
    default: true,
  },
})

const tableWrap = ref()
const tableHeight = ref('0px')

const emits = defineEmits(['onDataChange', 'update:query'])
const { loading, setLoading } = useLoading()

const pagination = reactive({
  current: 1,
  pageSize: 10,
  total: 0,
  showTotal: true,
  showPageSize: true,
})
const tableData = ref([])
const initQuery = { ...props.query }

function init() {
  tableHeight.value = tableWrap.value?.offsetHeight || 0 + 'px'
}

const scroll = computed(() => {
  const tHeader = tableWrap.value?.querySelector('.ant-table-thead')
  return {
    y: tableWrap.value?.offsetHeight - tHeader?.offsetHeight,
  }
})

const myQuery = onQueryChange()

watch(
  () => props.query,
  () => {
    myQuery()
  },
  {
    deep: true,
  },
)

function onQueryChange() {
  return utils.debounce(() => {
    handleQuery()
  }, 1000)
}

window.onresize = () => init()

async function handleQuery(loading?: boolean) {
  try {
    setLoading(loading === undefined ? true : loading)
    let paginationParams: PageQueryDto<typeof props.query> = {
      page: 1,
      size: 10,
      sort: props.defaultSort,
      order: 'desc',
    }
    if (props.isPagination && props.remote) {
      paginationParams.page = pagination.current
      paginationParams.size = pagination.pageSize
      paginationParams.model = { ...props.query }

      const { data } = await props.getData(paginationParams)
      tableData.value = data.record
      pagination.total = data.total
    } else {
      const { data } = await props.getData(paginationParams)
      tableData.value = data.record || data || []
    }
  } catch (error) {
    tableData.value = []
    pagination.total = 0
  } finally {
    emits('onDataChange', tableData.value)
    setLoading(false)
  }
}

async function handleReset() {
  const queryItems = { ...props.query }
  for (const queryItemsKey in queryItems) {
    queryItems[queryItemsKey] = null
  }

  emits('update:query', { ...queryItems, ...initQuery })
  await nextTick()
  pagination.current = 1
  await handleQuery()
}

function handleSearch(loading?: boolean) {
  pagination.current = 1
  handleQuery(loading)
}

function onPageChange(page: number, size: number) {
  pagination.current = page
  pagination.pageSize = size
  if (props.remote) {
    handleQuery()
  }
}

function onSizeChange(size: number) {
  pagination.current = 1
  pagination.pageSize = size
  if (props.remote) {
    handleQuery()
  }
}

onMounted(init)

defineExpose({
  handleSearch,
  handleReset,
  handleQuery,
})
</script>

<style lang="less" scoped>
.app-crud {
  ::v-deep(.ant-table) {
    &-body {
      overflow-y: auto !important;
    }
  }
}
</style>
